﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using HengTong.Model;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;
using HengTong.Model._Admin;
using HengTong.Model.Db.System;
using Microsoft.EntityFrameworkCore;
using TiaoTaoHelper.Models;
using TiaoTaoHelper.Wtm.Models;

namespace HengTong.ViewModel._Admin.FrameworkUserVMs
{
    public partial class FrameworkUserListVm : BasePagedListVM<FrameworkUserView, FrameworkUserSearcher>
    {
        protected override IEnumerable<IGridColumn<FrameworkUserView>> InitGridHeader()
        {
            return new List<GridColumn<FrameworkUserView>>
            {
                this.MakeGridHeader(x => x.FrameworkUserItCode).SetTitle(@Localizer["Sys.Account"].Value),
                this.MakeGridHeader(x => x.FrameworkUserName).SetTitle(@Localizer["_Admin.Name"].Value),
                this.MakeGridHeader(x => x.FrameworkUserGender).SetTitle(@Localizer["_Admin.Gender"].Value),
                this.MakeGridHeader(x => x.FrameworkUserCellPhone).SetTitle(@Localizer["_Admin.CellPhone"].Value),
                this.MakeGridHeader(x => x.FrameworkUserRole).SetTitle(@Localizer["_Admin.Role"].Value),
                this.MakeGridHeader(x => x.FrameworkUserGroup).SetTitle(@Localizer["_Admin.Group"].Value),
                this.MakeGridHeader(x => x.FrameworkUserIsValid).SetTitle(@Localizer["_Admin.IsValid"].Value),
                this.MakeGridHeader(x => x.FrameworkUserPhoto).SetTitle(@Localizer["_Admin.Photo"].Value),
                this.MakeGridHeaderAction(width: 200)
            };
        }

        public override IOrderedQueryable<FrameworkUserView> GetSearchQuery()
        {
            List<string> userList = new List<string>();
            if (Searcher.GroupId != null && Searcher.GroupId != Guid.Empty)
            {
                var group = DC.Set<SysGroup>().FirstOrDefault(e => e.ID == Searcher.GroupId);
                if (group == null)
                {
                    MSD.AddModelError(" ", "所属部门不存在");
                    return null;
                }

                userList = DC.Set<FrameworkUserGroup>()
                    .Where(e => e.GroupCode == group.GroupCode)
                    .Select(e => e.UserCode)
                    .ToList();
            }

            var query = DC.Set<FrameworkUser>()
                .CheckContain(Searcher.ITCode, x => x.ITCode)
                .CheckContain(Searcher.Name, x => x.Name)
                .CheckEqual(Searcher.IsValid, x => x.IsValid)
                .CheckWhere(Searcher.GroupId, x => userList.Contains(x.ITCode))
                .Select(x => new FrameworkUserView
                {
                    ID = x.ID,
                    FrameworkUserItCode = x.ITCode,
                    FrameworkUserName = x.Name,
                    FrameworkUserCellPhone = x.CellPhone,
                    FrameworkUserRole = DC.Set<FrameworkUserRole>().Where(y => y.UserCode == x.ITCode)
                        .Join(DC.Set<FrameworkRole>(), ur => ur.RoleCode, role => role.RoleCode, (ur, role) => role)
                        .Select(y0 => y0.RoleName).ToSepratedString(null, ","),
                    FrameworkUserGroup = DC.Set<FrameworkUserGroup>().Where(y => y.UserCode == x.ITCode)
                        .Join(DC.Set<SysGroup>(), ug => ug.GroupCode, group => group.GroupCode, (ug, group) => group)
                        .Select(y0 => y0.GroupName).ToSepratedString(null, ","),
                    FrameworkUserIsValid = x.IsValid,
                    FrameworkUserPhoto = x.PhotoId,
                })
                .OrderBy(x => x.ID);
            return query;
        }

        public async Task<Result<List<CommonUserInfoView>>> GetAllUserInfoForThirdPartyAsync(Guid? userId = null,
            string userCode = null,
            string phone = null,
            DateTime? lastSyncTime = null)
        {
            try
            {
                var userJobPositions = await DC.Set<SysUserJobPosition>()
                    .Where(u => u.User.IsValid)
                    .CheckEqual(userId, x => x.User.ID)
                    .CheckEqual(userCode, x => x.User.ITCode)
                    .CheckEqual(phone, x => x.User.CellPhone)
                    .CheckWhere(lastSyncTime, x => x.User.UpdateTime >= lastSyncTime.Value ||
                                                   x.User.CreateTime >= lastSyncTime.Value ||
                                                   x.JobPosition.UpdateTime >= lastSyncTime.Value ||
                                                   x.JobPosition.CreateTime >= lastSyncTime.Value)
                    .Include(e => e.JobPosition)
                    .ThenInclude(e => e.Group) // 包含岗位所属部门
                    .Include(e => e.JobPosition)
                    .ThenInclude(e => e.Organizations)
                    .ThenInclude(e => e.Org) // 包含组织机构信息
                    .Include(e => e.User)
                    .ThenInclude(e => e.Person)
                    .ToListAsync();

                var data = userJobPositions
                    .GroupBy(u => u.User.ID)
                    .Select(g => new CommonUserInfoView
                    {
                        Id = g.Key,
                        Name = g.First().User.Name,
                        ITCode = g.First().User.ITCode,
                        CellPhone = g.First().User.CellPhone,
                        Gender = g.First().User.Person?.Gender,
                        CreateTime = g.First().User.CreateTime,
                        UpdateTime = g.First().User.UpdateTime,
                        JobPositions = g.Select(ujp => new UserJobPositionInfo
                        {
                            Id = ujp.JobPosition.ID,
                            Code = ujp.JobPosition.Code,
                            Name = ujp.JobPosition.Name,
                            IsMain = ujp.IsMain,
                            Department = ujp.JobPosition.Group != null
                                ? new DepartmentInfo
                                {
                                    Id = ujp.JobPosition.Group.ID,
                                    Name = ujp.JobPosition.Group.GroupName,
                                    Code = ujp.JobPosition.Group.GroupCode
                                }
                                : null,
                            Organizations = ujp.JobPosition.Organizations.Select(o => new OrganizationInfo
                            {
                                Id = o.Org.ID,
                                Name = o.Org.Name,
                                Code = o.Org.Code
                            }).ToList()
                        }).ToList()
                    })
                    .ToList();

                return new Result<List<CommonUserInfoView>>
                {
                    Data = data
                };
            }
            catch (Exception ex)
            {
                return new Result<List<CommonUserInfoView>>($"获取用户信息失败：{ex.Message}");
            }
        }
    }

    public class FrameworkUserView : FrameworkUser
    {
        public string FrameworkUserItCode { get; set; }
        public string FrameworkUserName { get; set; }
        public Gender? FrameworkUserGender { get; set; }
        public string FrameworkUserCellPhone { get; set; }
        public string FrameworkUserRole { get; set; }
        public string FrameworkUserGroup { get; set; }
        public bool? FrameworkUserIsValid { get; set; }
        public Guid? FrameworkUserPhoto { get; set; }
    }

    public class CommonUserInfoView
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string ITCode { get; set; }
        public string CellPhone { get; set; }
        public Gender? Gender { get; set; }
        public DateTime? UpdateTime { get; set; }
        public DateTime? CreateTime { get; set; }
        public List<UserJobPositionInfo> JobPositions { get; set; } = new List<UserJobPositionInfo>();
    }

    public class UserJobPositionInfo
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string Code { get; set; }
        public bool IsMain { get; set; }
        public DepartmentInfo Department { get; set; }
        public List<OrganizationInfo> Organizations { get; set; } = new List<OrganizationInfo>();
    }

    public class DepartmentInfo
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string Code { get; set; }
    }

    public class OrganizationInfo
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string Code { get; set; }
    }
}